#include "database/file_repository.h"
#include "database/file_system_status.h"
#include <QDebug>
#include <QSet>
#include <QMap>
#include <QPair>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>

FileRepository::FileRepository(QSqlDatabase &database, const QString &currentUserId)
    : m_database(database)
    , m_currentUserId(currentUserId)
{
}

bool FileRepository::isDatabaseConnected() const
{
    return m_database.isOpen() && m_database.isValid();
}

KmsFile FileRepository::mapFromQuery(const QSqlQuery &query) const
{
    KmsFile file;
    file.id = query.value("ID").toString();
    file.name = query.value("NAME").toString();
    file.diskId = query.value("DISK_ID").toString();
    file.folderId = query.value("FOLDER_ID").toString();
    file.creator = query.value("CREATOR").toString();
    file.creatorId = query.value("CREATOR_ID").toString();
    file.type = query.value("TYPE").toString();
    file.createDate = query.value("CREATE_DATE").toString();
    file.lastModifyDate = query.value("LAST_MODIFY_DATE").toString();
    file.originType = query.value("ORIGIN_TYPE").toInt();
    file.originId = query.value("ORIGIN_ID").toString();
    file.size = query.value("SIZE").toLongLong();
    file.removeOperator = query.value("REMOVE_OPERATOR").toString();
    file.status = query.value("STATUS").toInt();
    file.checksum = query.value("CHECKSUM").toString();
    file.localFileSize = query.value("LOCAL_FILE_SIZE").toLongLong();
    file.localFileChecksum = query.value("LOCAL_FILE_CHECKSUM").toString();
    file.localFilePath = query.value("LOCAL_FILE_PATH").toString();
    file.version = query.value("VERSION").toInt();
    file.userId = query.value("USER_ID").toString();
    return file;
}

bool FileRepository::insert(const KmsFile &file)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return false;
    }
    
    QSqlQuery query(m_database);
    query.prepare("INSERT INTO kms_file (ID, NAME, DISK_ID, FOLDER_ID, CREATOR, CREATOR_ID, "
                  "TYPE, CREATE_DATE, LAST_MODIFY_DATE, ORIGIN_TYPE, ORIGIN_ID, SIZE, "
                  "REMOVE_OPERATOR, STATUS, CHECKSUM, LOCAL_FILE_SIZE, LOCAL_FILE_CHECKSUM, LOCAL_FILE_PATH, VERSION, USER_ID) "
                  "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
    
    query.addBindValue(file.id);
    query.addBindValue(file.name);
    query.addBindValue(file.diskId);
    query.addBindValue(file.folderId);
    query.addBindValue(file.creator);
    query.addBindValue(file.creatorId);
    query.addBindValue(file.type);
    query.addBindValue(file.createDate);
    query.addBindValue(file.lastModifyDate);
    query.addBindValue(file.originType);
    query.addBindValue(file.originId);
    query.addBindValue(file.size);
    query.addBindValue(file.removeOperator);
    query.addBindValue(file.status);
    query.addBindValue(file.checksum);
    query.addBindValue(file.localFileSize);
    query.addBindValue(file.localFileChecksum);
    query.addBindValue(file.localFilePath);
    query.addBindValue(file.version);
    QString userId = file.userId.isEmpty() ? m_currentUserId : file.userId;
    query.addBindValue(userId);
    
    if (!query.exec()) {
        qDebug() << "插入文件记录失败:" << query.lastError().text();
        return false;
    }
    
    return true;
}

bool FileRepository::update(const KmsFile &file)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return false;
    }
    
    QSqlQuery query(m_database);
    query.prepare("UPDATE kms_file SET NAME=?, DISK_ID=?, FOLDER_ID=?, CREATOR=?, CREATOR_ID=?, "
                  "TYPE=?, CREATE_DATE=?, LAST_MODIFY_DATE=?, ORIGIN_TYPE=?, ORIGIN_ID=?, SIZE=?, "
                  "REMOVE_OPERATOR=?, STATUS=?, CHECKSUM=?, LOCAL_FILE_SIZE=?, LOCAL_FILE_CHECKSUM=?, LOCAL_FILE_PATH=?, VERSION=? WHERE ID=?");
    
    query.addBindValue(file.name);
    query.addBindValue(file.diskId);
    query.addBindValue(file.folderId);
    query.addBindValue(file.creator);
    query.addBindValue(file.creatorId);
    query.addBindValue(file.type);
    query.addBindValue(file.createDate);
    query.addBindValue(file.lastModifyDate);
    query.addBindValue(file.originType);
    query.addBindValue(file.originId);
    query.addBindValue(file.size);
    query.addBindValue(file.removeOperator);
    query.addBindValue(file.status);
    query.addBindValue(file.checksum);
    query.addBindValue(file.localFileSize);
    query.addBindValue(file.localFileChecksum);
    query.addBindValue(file.localFilePath);
    query.addBindValue(file.version);
    query.addBindValue(file.id);
    
    if (!query.exec()) {
        qDebug() << "更新文件记录失败:" << query.lastError().text();
        return false;
    }
    
    return true;
}

bool FileRepository::remove(const QString &fileId)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return false;
    }
    
    if (fileId.isEmpty()) {
        qDebug() << "文件ID为空，无法删除";
        return false;
    }
    
    QSqlQuery query(m_database);
    query.prepare("DELETE FROM kms_file WHERE ID = ?");
    query.addBindValue(fileId);
    
    if (!query.exec()) {
        qDebug() << "删除文件记录失败:" << query.lastError().text();
        return false;
    }
    
    if (query.numRowsAffected() > 0) {
        qDebug() << "成功删除文件记录，文件ID:" << fileId;
        return true;
    } else {
        qDebug() << "未找到匹配的文件记录，文件ID:" << fileId;
        return false;
    }
}

KmsFile FileRepository::findById(const QString &fileId)
{
    KmsFile file;
    
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return file;
    }
    
    QSqlQuery query(m_database);
    query.prepare("SELECT * FROM kms_file WHERE ID = ?");
    query.addBindValue(fileId);
    
    if (!query.exec()) {
        qDebug() << "根据ID查询文件记录失败:" << query.lastError().text();
        return file;
    }
    
    if (query.next()) {
        file = mapFromQuery(query);
    }
    
    return file;
}

QList<KmsFile> FileRepository::findByFolderId(const QString &folderId)
{
    QList<KmsFile> files;
    
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return files;
    }
    
    QSqlQuery query(m_database);
    query.prepare("SELECT * FROM kms_file WHERE FOLDER_ID = ?");
    query.addBindValue(folderId);
    
    if (!query.exec()) {
        qDebug() << "查询文件失败:" << query.lastError().text();
        return files;
    }
    
    while (query.next()) {
        files.append(mapFromQuery(query));
    }
    
    return files;
}

QList<KmsFile> FileRepository::findByPath(const QString &path)
{
    QList<KmsFile> files;
    
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return files;
    }
    
    qDebug() << "警告：queryFilesByPath方法已废弃（PATH字段已移除）";
    return files;
}

QList<KmsFile> FileRepository::findAll()
{
    QList<KmsFile> files;
    
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return files;
    }
    
    QSqlQuery query(m_database);
    query.prepare("SELECT * FROM kms_file");
    
    if (!query.exec()) {
        qDebug() << "查询所有文件记录失败:" << query.lastError().text();
        return files;
    }
    
    while (query.next()) {
        files.append(mapFromQuery(query));
    }
    
    return files;
}

KmsFile FileRepository::findByLocalFilePath(const QString &localFilePath)
{
    KmsFile file;
    
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return file;
    }
    
    if (localFilePath.isEmpty()) {
        qDebug() << "本地文件路径为空，无法查询";
        return file;
    }
    
    // 规范化路径（统一使用正斜杠）
    QString normalizedPath = localFilePath;
    normalizedPath.replace('\\', '/');
    // 去掉开头的斜杠（如果存在）
    if (normalizedPath.startsWith('/')) {
        normalizedPath = normalizedPath.mid(1);
    }
    
    QSqlQuery query(m_database);
    query.prepare("SELECT * FROM kms_file WHERE LOCAL_FILE_PATH = ?");
    query.addBindValue(normalizedPath);
    
    if (!query.exec()) {
        qDebug() << "根据本地文件路径查询文件记录失败:" << query.lastError().text();
        return file;
    }
    
    if (query.next()) {
        file = mapFromQuery(query);
        qDebug() << "找到匹配的文件记录，文件ID:" << file.id << "本地路径:" << file.localFilePath;
    } else {
        qDebug() << "未找到匹配的文件记录，本地路径:" << normalizedPath;
    }
    
    return file;
}

bool FileRepository::updateFromJson(const QJsonObject &fileData)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return false;
    }
    
    QString fileId = fileData["id"].toString();
    if (fileId.isEmpty()) {
        qDebug() << "文件ID为空，无法更新";
        return false;
    }
    
    QSqlQuery query(m_database);
    query.prepare("UPDATE kms_file SET "
                  "NAME = ?, DISK_ID = ?, FOLDER_ID = ?, ORIGIN_TYPE = ?, ORIGIN_ID = ?, "
                  "SIZE = ?, REMOVE_OPERATOR = ?, STATUS = ?, CHECKSUM = ? "
                  "WHERE ID = ?");
    
    query.addBindValue(fileData["name"].toString());
    query.addBindValue(fileData["diskId"].toString());
    query.addBindValue(fileData["folderId"].toString());
    query.addBindValue(fileData["originType"].toInt());
    query.addBindValue(fileData["originId"].toString());
    query.addBindValue(fileData["size"].toVariant());
    query.addBindValue(fileData["removeOperator"].toString());
    query.addBindValue(fileData["delete"].toBool() ? 0 : 1);
    query.addBindValue(fileData["checksum"].toString());
    query.addBindValue(fileId);
    
    if (!query.exec()) {
        qDebug() << "更新文件信息失败:" << query.lastError().text();
        return false;
    }
    
    qDebug() << "成功更新文件信息，文件ID:" << fileId;
    return true;
}

bool FileRepository::updateLocalFileInfo(const QString &fileId, qint64 localFileSize, const QString &localFileChecksum, const QString &localFilePath)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接，无法更新本地文件信息";
        return false;
    }
    
    QSqlQuery query(m_database);
    if (!localFilePath.isEmpty()) {
        query.prepare("UPDATE kms_file SET LOCAL_FILE_SIZE = ?, LOCAL_FILE_CHECKSUM = ?, LOCAL_FILE_PATH = ? WHERE ID = ?");
        query.addBindValue(localFileSize);
        query.addBindValue(localFileChecksum);
        query.addBindValue(localFilePath);
        query.addBindValue(fileId);
    } else {
        query.prepare("UPDATE kms_file SET LOCAL_FILE_SIZE = ?, LOCAL_FILE_CHECKSUM = ? WHERE ID = ?");
        query.addBindValue(localFileSize);
        query.addBindValue(localFileChecksum);
        query.addBindValue(fileId);
    }
    
    if (query.exec()) {
        qDebug() << "成功更新本地文件信息，文件ID:" << fileId << "大小:" << localFileSize << "本地校验和:" << localFileChecksum << "本地路径:" << localFilePath;
        return true;
    } else {
        qDebug() << "更新本地文件信息失败:" << query.lastError().text();
        return false;
    }
}

bool FileRepository::clearLocalFileInfo(const QString &fileId)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接，无法清除本地文件信息";
        return false;
    }
    
    QSqlQuery query(m_database);
    query.prepare("UPDATE kms_file SET LOCAL_FILE_SIZE = 0, LOCAL_FILE_CHECKSUM = NULL, LOCAL_FILE_PATH = NULL WHERE ID = ?");
    query.addBindValue(fileId);
    
    if (query.exec()) {
        qDebug() << "成功清除本地文件信息，文件ID:" << fileId;
        return true;
    } else {
        qDebug() << "清除本地文件信息失败:" << query.lastError().text();
        return false;
    }
}

bool FileRepository::updateStatus(const QString &fileId, int status)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接，无法更新文件状态";
        return false;
    }
    QSqlQuery query(m_database);
    query.prepare("UPDATE kms_file SET STATUS = ? WHERE ID = ?");
    query.addBindValue(status);
    query.addBindValue(fileId);
    if (!query.exec()) {
        qDebug() << "更新文件状态失败:" << query.lastError().text();
        return false;
    }
    qDebug() << "成功更新文件状态，文件ID:" << fileId << "状态:" << status;
    return true;
}

bool FileRepository::syncFromJson(const QJsonArray &filesData)
{
    if (!m_database.isOpen()) {
        qDebug() << "数据库未打开，无法同步文件数据";
        return false;
    }
    
    try {
        m_database.transaction();
        
        // 查询现有文件记录，包括 ID, VERSION, STATUS
        QMap<QString, QPair<int, int>> existingFiles; // key: fileId, value: <version, status>
        QSqlQuery selectQuery(m_database);
        if (selectQuery.exec("SELECT ID, VERSION, STATUS FROM kms_file")) {
            while (selectQuery.next()) {
                QString id = selectQuery.value(0).toString();
                int version = selectQuery.value(1).toInt();
                int status = selectQuery.value(2).toInt();
                existingFiles[id] = QPair<int, int>(version, status);
            }
        }
        
        // 准备 SQL 语句
        QSqlQuery insertQuery(m_database);
        insertQuery.prepare("INSERT INTO kms_file (ID, NAME, DISK_ID, FOLDER_ID, CREATOR, CREATOR_ID, TYPE, CREATE_DATE, LAST_MODIFY_DATE, ORIGIN_TYPE, ORIGIN_ID, SIZE, REMOVE_OPERATOR, CHECKSUM, VERSION, STATUS, USER_ID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
        
        QSqlQuery updateQuery(m_database);
        updateQuery.prepare("UPDATE kms_file SET NAME=?, DISK_ID=?, FOLDER_ID=?, CREATOR=?, CREATOR_ID=?, TYPE=?, CREATE_DATE=?, LAST_MODIFY_DATE=?, ORIGIN_TYPE=?, ORIGIN_ID=?, SIZE=?, REMOVE_OPERATOR=?, CHECKSUM=?, VERSION=?, STATUS=?, USER_ID=? WHERE ID=?");
        
        QSqlQuery updateStatusQuery(m_database);
        updateStatusQuery.prepare("UPDATE kms_file SET STATUS=? WHERE ID=?");
        
        QSqlQuery deleteQuery(m_database);
        deleteQuery.prepare("DELETE FROM kms_file WHERE ID=?");
        
        QSet<QString> processedFileIds;
        int insertCount = 0;
        int updateCount = 0;
        int deleteCount = 0;
        int skipCount = 0;
        
        for (const QJsonValue &value : filesData) {
            if (!value.isObject()) {
                qDebug() << "跳过非对象类型的文件数据";
                continue;
            }
            
            QJsonObject fileObj = value.toObject();
            
            QString id = fileObj["id"].toString();
            if (id.isEmpty()) {
                qDebug() << "跳过ID为空的文件数据";
                continue;
            }
            
            bool isDelete = fileObj["delete"].toBool(false);
            int serverVersion = fileObj["version"].toInt(0);
            
            processedFileIds.insert(id);
            
            // 检查记录是否存在
            bool exists = existingFiles.contains(id);
            
            if (!isDelete) {
                // filesData 有记录且 isDelete=false
                if (!exists) {
                    // kms_file 表记录不存在，插入新记录，status=0（待下载）
                    QString name = fileObj["name"].toString();
                    QString diskId = fileObj["diskId"].toString();
                    QString folderId = fileObj["folderId"].toString();
                    QString creator = fileObj["creator"].toString();
                    QString creatorId = fileObj["creatorId"].toString();
                    QString type = fileObj["type"].toString();
                    QString createDate = fileObj["createDate"].toString();
                    QString lastModifyDate = fileObj["lastModifyDate"].toString();
                    int originType = fileObj["originType"].toInt();
                    QString originId = fileObj["originId"].toString();
                    qint64 size = fileObj["size"].toVariant().toLongLong();
                    QString removeOperator = fileObj["removeOperator"].toString();
                    QString checksum = fileObj["checksum"].toString();
                    
                    insertQuery.bindValue(0, id);
                    insertQuery.bindValue(1, name);
                    insertQuery.bindValue(2, diskId);
                    insertQuery.bindValue(3, folderId);
                    insertQuery.bindValue(4, creator);
                    insertQuery.bindValue(5, creatorId);
                    insertQuery.bindValue(6, type);
                    insertQuery.bindValue(7, createDate);
                    insertQuery.bindValue(8, lastModifyDate);
                    insertQuery.bindValue(9, originType);
                    insertQuery.bindValue(10, originId);
                    insertQuery.bindValue(11, size);
                    insertQuery.bindValue(12, removeOperator);
                    insertQuery.bindValue(13, checksum);
                    insertQuery.bindValue(14, serverVersion);
                    insertQuery.bindValue(15, FileSystemStatus::PENDING_DOWNLOAD); // status = 待下载
                    insertQuery.bindValue(16, m_currentUserId);
                    
                    if (!insertQuery.exec()) {
                        qDebug() << "插入文件记录失败:" << insertQuery.lastError().text() << "文件ID:" << id;
                    } else {
                        insertCount++;
                    }
                } else {
                    // kms_file 表记录存在
                    int existingVersion = existingFiles[id].first;
                    int existingStatus = existingFiles[id].second;
                    
                    if (serverVersion == existingVersion) {
                        // version 一致，不做处理
                        skipCount++;
                    } else if (serverVersion > existingVersion) {
                        // filesData version > kms_file version，需要更新
                        QString name = fileObj["name"].toString();
                        QString diskId = fileObj["diskId"].toString();
                        QString folderId = fileObj["folderId"].toString();
                        QString creator = fileObj["creator"].toString();
                        QString creatorId = fileObj["creatorId"].toString();
                        QString type = fileObj["type"].toString();
                        QString createDate = fileObj["createDate"].toString();
                        QString lastModifyDate = fileObj["lastModifyDate"].toString();
                        int originType = fileObj["originType"].toInt();
                        QString originId = fileObj["originId"].toString();
                        qint64 size = fileObj["size"].toVariant().toLongLong();
                        QString removeOperator = fileObj["removeOperator"].toString();
                        QString checksum = fileObj["checksum"].toString();
                        
                        int newStatus;
                        int newVersion;
                        if (FileSystemStatus::isPendingDelete(existingStatus)) {
                            // 原记录 status = 待提交删除，设置 status = 本地删除冲突
                            newStatus = FileSystemStatus::LOCAL_DELETE_CONFLICT;
                            // 保留 本地版本
                            newVersion = existingVersion;
                        } else if (FileSystemStatus::isPendingDownload(existingStatus) || FileSystemStatus::isSynced(existingStatus)) {
                            // 原记录 status = 待下载 或 已同步，设置 status = 待下载
                            newStatus = FileSystemStatus::PENDING_DOWNLOAD;
                            // 使用 服务器版本
                            newVersion = serverVersion;
                        } else if (FileSystemStatus::isPendingModify(existingStatus)) {
                            // 原记录 status = 待提交变更，设置 status = 变更冲突
                            newStatus = FileSystemStatus::MODIFY_CONFLICT;
                            // 保留 本地版本
                            newVersion = existingVersion;
                        } else {
                            // 其他状态保持原状态或设置为待下载
                            newStatus = FileSystemStatus::PENDING_DOWNLOAD;
                            // 使用 服务器版本
                            newVersion = serverVersion;
                        }
                        
                        updateQuery.bindValue(0, name);
                        updateQuery.bindValue(1, diskId);
                        updateQuery.bindValue(2, folderId);
                        updateQuery.bindValue(3, creator);
                        updateQuery.bindValue(4, creatorId);
                        updateQuery.bindValue(5, type);
                        updateQuery.bindValue(6, createDate);
                        updateQuery.bindValue(7, lastModifyDate);
                        updateQuery.bindValue(8, originType);
                        updateQuery.bindValue(9, originId);
                        updateQuery.bindValue(10, size);
                        updateQuery.bindValue(11, removeOperator);
                        updateQuery.bindValue(12, checksum);
                        updateQuery.bindValue(13, newVersion);
                        updateQuery.bindValue(14, newStatus);
                        updateQuery.bindValue(15, m_currentUserId);
                        updateQuery.bindValue(16, id);
                        
                        if (!updateQuery.exec()) {
                            qDebug() << "更新文件记录失败:" << updateQuery.lastError().text() << "文件ID:" << id;
                        } else {
                            updateCount++;
                        }
                    }
                    // 如果 serverVersion < existingVersion，不做处理（本地版本更新）
                }
            } else {
                // filesData 有记录且 isDelete=true
                if (!exists) {
                    // kms_file 表记录不存在，不做处理
                    skipCount++;
                } else {
                    // kms_file 表记录存在
                    int existingVersion = existingFiles[id].first;
                    int existingStatus = existingFiles[id].second;
                    
                    if (serverVersion > existingVersion) {
                        if (FileSystemStatus::isPendingDownload(existingStatus) || FileSystemStatus::isSynced(existingStatus)) {
                            // 原记录 status = 待下载 或 已同步，删除记录
                            deleteQuery.bindValue(0, id);
                            if (!deleteQuery.exec()) {
                                qDebug() << "删除文件记录失败:" << deleteQuery.lastError().text() << "文件ID:" << id;
                            } else {
                                deleteCount++;
                            }
                        } else if (FileSystemStatus::isPendingModify(existingStatus) || FileSystemStatus::isModifyConflict(existingStatus)) {
                            // 原记录 status = 待提交变更 或 变更冲突，设置 status = 服务器删除冲突
                            updateStatusQuery.bindValue(0, FileSystemStatus::SERVER_DELETE_CONFLICT);
                            updateStatusQuery.bindValue(1, id);
                            if (!updateStatusQuery.exec()) {
                                qDebug() << "更新文件状态失败:" << updateStatusQuery.lastError().text() << "文件ID:" << id;
                            } else {
                                updateCount++;
                            }
                        }
                        else if (FileSystemStatus::isPendingDelete(existingStatus)) {
                            // 原记录 status = 待提交删除，设置 status = 本地删除冲突
                            updateStatusQuery.bindValue(0, FileSystemStatus::LOCAL_DELETE_CONFLICT);
                            updateStatusQuery.bindValue(1, id);
                            if (!updateStatusQuery.exec()) {
                                qDebug() << "更新文件状态失败:" << updateStatusQuery.lastError().text() << "文件ID:" << id;
                            } else {
                                updateCount++;
                            }
                        }
                    }
                    // 如果 serverVersion <= existingVersion，不做处理
                }
            }
        }
        
        m_database.commit();
        qDebug() << "同步文件数据完成 - 插入:" << insertCount << "更新:" << updateCount << "删除:" << deleteCount << "跳过:" << skipCount;
        return true;
        
    } catch (const std::exception &e) {
        qDebug() << "同步文件数据时发生异常:" << e.what();
        m_database.rollback();
        return false;
    } catch (...) {
        qDebug() << "同步文件数据时发生异常";
        m_database.rollback();
        return false;
    }
}

